package com.dreamers.pathcore;

import java.io.*;
import java.text.SimpleDateFormat;
import java.util.Date;

public class LogUtil {

    public static LogUtil INSTANCE = new LogUtil();

    int fileIndex = 1;

    private String formatStr = "yyyy-MM-dd HH-mm-ss";

    private SimpleDateFormat sdfDirName = new SimpleDateFormat("yyyyMMdd HHmmss");

    private SimpleDateFormat sdfConsoleOupt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    private String logFileStorePath = null;

    private String logPath = null;

    private File logFile = null;

    private String originFileName = "log.txt";

    private BufferedWriter bw = null;

    private boolean isWriteTimeONConsole = false;

    private boolean isCreateDirParentWithTime = true;

    private long maxSize = 1024 * 1024 * 5;//文件最大大小,单位字节，大于这个数字后生成第二个日志文件


    public LogUtil() {
        setMaxLogsize(1);
        setWriteTimeONConsole(true);
        //refreshLogFileStorePathConfig("d:/logs/center");
        initLogConfig();
    }


    public LogUtil(String logFileStorePath) {
        this.logFileStorePath = logFileStorePath;
        initLogConfig();
    }


    public LogUtil(String logFileStorePath, String originFileName) {
        this(logFileStorePath);
        this.originFileName = originFileName;
        initLogConfig();
    }


    public LogUtil(String logFileStorePath, String originFileName, boolean isWriteTimeONConsole) {
        this(logFileStorePath, originFileName);
        this.isWriteTimeONConsole = isWriteTimeONConsole;
        initLogConfig();
    }


    public LogUtil(String logFileStorePath, String originFileName,
                   boolean isWriteTimeONConsole, boolean isCreateDirParentWithTime) {
        this(logFileStorePath, originFileName, isWriteTimeONConsole);
        this.isCreateDirParentWithTime = isCreateDirParentWithTime;
        initLogConfig();
    }


    public LogUtil(String logFileStorePath, String originFileName,
                   boolean isWriteTimeONConsole, boolean isCreateDirParentWithTime, long maxSize) {
        this(logFileStorePath, originFileName, isWriteTimeONConsole, isCreateDirParentWithTime);
        this.maxSize = maxSize;
        initLogConfig();
    }


    private void initLogConfig() {
        initFormatStr(this.formatStr);
        initLogFileStorePath(this.logFileStorePath);
        initLogFile();
    }


    private void initFormatStr(String formatStr) {
        sdfDirName = new SimpleDateFormat(formatStr);
    }


    private void initLogFileStorePath(String logFileStorePath) {
        if (logFileStorePath == null) {
            String currentAbsolutePath = this.getClass().getResource("").getPath();//当前class根路径
            String curDiskRootPath = currentAbsolutePath.substring(1, 4);//当前磁盘分区根路径
            logFileStorePath = curDiskRootPath + "/logs/info";
        }
        if (isCreateDirParentWithTime) {
            logPath = logFileStorePath + "/" + sdfDirName.format(new Date());
        } else {
            logPath = logFileStorePath;
        }
    }


    private void initLogFile() {
        File parentDirOflogFile = new File(logPath);
        if (!parentDirOflogFile.exists()) {
            parentDirOflogFile.mkdirs();
        }
        logFile = new File(logPath + "/" + this.originFileName);
        try {
            if (!logFile.exists()) {
                logFile.createNewFile();
            }
            Writer out = new FileWriter(logFile, true);
            bw = new BufferedWriter(out);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    private void createNewFile() throws IOException {
        String fileName = originFileName.substring(0, originFileName.lastIndexOf("."));
        String subfix = originFileName.substring(originFileName.lastIndexOf("."), originFileName.length());
        String newName = fileName + fileIndex + subfix;
        logFile = new File(logPath + "/" + newName);
        logFile.createNewFile();
        Writer out = new FileWriter(logFile, true);
        bw = new BufferedWriter(out);
        fileIndex++;
    }


    public void refreshLogConfig() {
        this.initLogConfig();
    }


    public void refreshDateFormatConfig(String formatStr) {
        sdfDirName = new SimpleDateFormat(formatStr);
    }


    public void refreshLogFileStorePathConfig(String logFileStorePath) {
        initLogFileStorePath(logFileStorePath);
        initLogFile();
    }


    private void writeToDoc(String str) {
        try {
            if (logFile.length() > maxSize) {
                createNewFile();
            }
            bw.write(str);
            bw.newLine();
            bw.flush();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    public void newLine() {
        try {
            bw.newLine();
            bw.flush();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }


    public String debug(String str) {
        String outputInfo = null;
        if (isWriteTimeONConsole) {
            String time = sdfConsoleOupt.format(new Date());
            outputInfo = time + ": " + str;
        } else {
            outputInfo = str;
        }
        System.out.println(outputInfo);
        return outputInfo;
    }


    public void info(String str) {
        writeToDoc(debug(str));
    }


    private void setFormatStr(String formatStr) {
        this.formatStr = formatStr;
    }


    public void setLogFileStorePath(String logFileStorePath) {
        this.logFileStorePath = logFileStorePath;
    }


    public String getLogFileStorePath() {
        return logPath;
    }


    public void setOriginFileName(String originFileName) {
        this.originFileName = originFileName;
    }


    public String getOriginFileName() {
        return originFileName;
    }


    public void setMaxLogsize(int size) {
        maxSize = 1024 * 1024 * size;
    }


    public long getMaxLogsize() {
        return maxSize;
    }


    public boolean isCreateDirParentWithTime() {
        return isCreateDirParentWithTime;
    }


    public void setCreateDirParentWithTime(boolean isCreateDirParentWithTime) {
        this.isCreateDirParentWithTime = isCreateDirParentWithTime;
    }


    public boolean isWriteTimeONConsole() {
        return isWriteTimeONConsole;
    }


    public void setWriteTimeONConsole(boolean isWriteTimeONConsole) {
        this.isWriteTimeONConsole = isWriteTimeONConsole;
    }
}